package team.seekers.hula.auth.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import team.seekers.hula.common.annotation.ApiResponseBody;
import team.seekers.hula.common.entity.UserSessionDTO;
import team.seekers.hula.common.entity.enums.LoginTypeEnum;
import team.seekers.hula.common.entity.result.ApiException;
import team.seekers.hula.common.entity.result.ApiExceptionEnum;
import team.seekers.hula.common.utils.AssertUtils;
import team.seekers.hula.common.utils.JwtUtil;
import team.seekers.hula.common.utils.WxUtil;
import team.seekers.hula.system.phoneMessage.service.PhoneMessageService;
import team.seekers.hula.user.user.entity.dao.UserDO;
import team.seekers.hula.user.user.entity.dto.LoginDTO;
import team.seekers.hula.user.user.entity.dto.UserCreateDTO;
import team.seekers.hula.user.user.service.UserService;

import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.Map;

import static team.seekers.hula.common.entity.result.ApiExceptionEnum.USER_ACCOUNT_ALREADY_EXIST;


@Controller
@ApiResponseBody
@RequestMapping("/login")
public class LoginController {

    @Autowired
    private UserService userService;

    @Autowired
    private PhoneMessageService phoneMessageService;

    @Autowired
    private JwtUtil jwtUtil;

    @PostMapping("/register")
    public String register(@RequestBody UserCreateDTO userCreateDTO) {
        //校验用户名
        QueryWrapper<UserDO> wrapper = new QueryWrapper<>();
        wrapper.eq("tel", userCreateDTO.getTel())
                .or().eq("union_id",userCreateDTO.getUnionId())
                .or().eq("account",userCreateDTO.getAccount());
        int count = userService.count(wrapper);
        if (count != 0){
            throw new ApiException(USER_ACCOUNT_ALREADY_EXIST);
        }
        return jwtUtil.getAndCacheJwtToken(userService.add(userCreateDTO));
    }

    @GetMapping("/univerify")
    public Map<String, Object> univerify(@RequestParam String tel) {
        // redis查找手机号
        UserSessionDTO userDO = userService.getUserSessionByTel(tel);
        Map<String, Object> map = new HashMap<>(2);
        if (userDO == null) {
            map.put("token", tel);
            map.put("toRegister", true);
        } else {
            String token = jwtUtil.getAndCacheJwtToken(userDO);
            map.put("token", token);
            map.put("toRegister", false);
        }
        return map;
    }

    @PostMapping("/account")
    public String accountLogin(@RequestBody LoginDTO loginDTO) {
        UserDO userDO = userService.getByPwd(loginDTO.getTel(), loginDTO.getAccount(),loginDTO.getPassword());
        AssertUtils.notNull(userDO, ApiExceptionEnum.PASSWORD_NOT_MATCHING);
        return jwtUtil.getAndCacheJwtToken(UserDO.toSessionDTO(userDO));
    }

    @PostMapping("/tel")
    public Map<String, Object>  login(@RequestBody LoginDTO loginDTO) {
        phoneMessageService.verifyCaptcha(loginDTO.getTel(),loginDTO.getCode());
        UserSessionDTO userSessionDTO = userService.getUserSessionByTel(loginDTO.getTel());
        HashMap<String, Object> map = new HashMap<>(2);
        if (userSessionDTO == null) {
            map.put("toRegister",true);
        }else {
            map.put("toRegister",false);
            map.put("token",jwtUtil.getAndCacheJwtToken(userSessionDTO));
        }
        return map;
    }


    @PostMapping("/wx")
    public Map<String, Object> wxLogin(@RequestBody @NotNull Map<String, String> json,
                                       @RequestHeader("user-agent") String userAgent){
        String code = json.get("code");
        String unionId = json.get("unionId");
        String openId = json.get("openId");
        if(StringUtils.isNotBlank(code)){
            LoginTypeEnum loginType = LoginTypeEnum.valueOf(json.get("loginType"));
            if(loginType.equals(LoginTypeEnum.MINI_APP) || loginType.equals(LoginTypeEnum.MP)){
                HashMap<String, String> idsMap = WxUtil.getUnionIdAndOpenId(code, loginType);
                unionId = idsMap.get("unionId");
                openId = idsMap.get("openId");
            }else{
                unionId = WxUtil.getUnionId(code,loginType);
            }
        }
        Map<String, Object> map = new HashMap<>(3);
        if(this.userService.isExistUnionId(unionId)){
            // openId绑定相关
            if(StringUtils.isNotBlank(openId)){
                userService.checkAndBindOpenId(unionId,openId,LoginTypeEnum.valueOf(json.get("loginType")));
            }

            // 根据unionId获取session
            UserDO userDO = this.userService.getByUnionId(unionId, userAgent);

            map.put("token", jwtUtil.getAndCacheJwtToken(UserDO.toSessionDTO(userDO)));
            map.put("toRegister",false);
        }else {
            map.put("toRegister",true);
            map.put("unionId",unionId);
            map.put("openId",openId);
        }
        return map;
    }
}
